﻿#include "GUIFESubSysAcousticDialog.h"
#include "ui_GUIFESubSysAcousticDialog.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKFESubSysAcoustic.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscNodeList.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"

#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsSpectraManager.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbstractSpectra.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"

#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h" 
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
#include <QStandardItemModel>

namespace GUI {
    GUIFESubSysAcousticDialog::GUIFESubSysAcousticDialog(Acoustics::FITKFESubSysAcoustic* obj, Core::FITKActionOperator* oper, QWidget* parent /*= nullptr*/) :
        GUIFESubSysBaseDialog(obj, oper, parent),
        _ui(new Ui::GUIFESubSysAcousticDialog)
    {
        _ui->setupUi(this);
        //初始化界面
        this->initWidgetImage();
        _tableView_Attributes = new QStandardItemModel();
        _ui->tableView_Attributes->setModel(_tableView_Attributes);
        _tableView_Elements = new QStandardItemModel();
        _ui->tableView_Elements->setModel(_tableView_Elements);
        _tableView_Nodes = new QStandardItemModel();
        _ui->tableView_Nodes->setModel(_tableView_Nodes);
        //初始化
        this->init();
    }

    GUIFESubSysAcousticDialog::~GUIFESubSysAcousticDialog()
    {
        //释放数据
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
        if (_tableView_Attributes) delete _tableView_Attributes;
        if (_tableView_Elements) delete _tableView_Elements;
        if (_tableView_Nodes) delete _tableView_Nodes;
    }

    void GUIFESubSysAcousticDialog::init()
    {
        Acoustics::FITKFESubSysAcoustic* data = dynamic_cast<Acoustics::FITKFESubSysAcoustic*>(_obj);
        if (!data || !_oper) return;
        //初始化界面参数
        this->initDampingLossComboBox();
        this->initFluidComboBox();
        //初始化数据
        QString name = _obj->getDataObjectName();
        if (name.isEmpty())
        {
            name = "FE Acoustic-1";
            name = this->ckeckNameFromMgr(name);
        }
        QList<int> fluidID = data->getAllElementPropID();
        bool isDamping = data->isDampingLoss();
        int dampingID = data->getDampingSpectraID();
        if (dampingID < 0)
            _oper->argValue<int>("DampingLossID", dampingID);
        //设置界面数据
        _ui->lineEdit_Name->setText(name);
        int index = 0;
        if (!fluidID.isEmpty())
            _ui->comboBox_Fluid->findData(fluidID.at(0));
        _ui->comboBox_Fluid->setCurrentIndex(index);
        index = _ui->comboBox_DampingLoss->findData(dampingID);
        _ui->comboBox_DampingLoss->setCurrentIndex(index);
        index = _ui->comboBox_Absorption->findData(dampingID);
        _ui->comboBox_Absorption->setCurrentIndex(index);
        if (isDamping)
            _ui->radioButton_DampingLoss->setChecked(true);
        else
            _ui->radioButton_Absorption->setChecked(false);
        this->initTableViewAttributes();
        this->initTableViewElements();
        this->initTableViewNodes();
    }

    void GUIFESubSysAcousticDialog::on_pushButton_Cancel_clicked()
    {
        //点击取消按键动作
        this->reject();
    }

    void GUIFESubSysAcousticDialog::on_pushButton_OK_clicked()
    {
        if (!_oper)return;
        //获取操作器动作类型
        QString operType;
        _oper->argValue<QString>("OperModelType", operType);
        if (operType.isEmpty())
        {
            delete _obj;
            this->reject();
            return;
        }
        //创建动作
        if (operType == "Create")
        {
            if (!this->createObjData())
                return;
        }
        //修改动作
        else if (operType == "Edit")
        {
            if (!this->editObjData())
                return;
        }
        this->accept();
    }

    void GUIFESubSysAcousticDialog::initWidgetImage()
    {
        //初始化图像
        _ui->label_Image->setPixmap(QPixmap(":/ToolBar/toolBar/FE_cavity_subsystem.png"));
    }

    void GUIFESubSysAcousticDialog::initTableViewAttributes()
    {
        if (!_obj) return;
        //获取属性
        QList<int> nodeIDs = _obj->getNodesID();
        QList<int> elemIDs = _obj->getElementsID();
        QString nodeStr = this->getIDListConsolidatedStr(nodeIDs);
        QString elemStr = this->getIDListConsolidatedStr(elemIDs);
        //设置表格
        _tableView_Attributes->clear();
        QStringList tableView_h_headers;
        tableView_h_headers << tr("Attribute") << tr("Count") << tr("IDs");
        _tableView_Attributes->setHorizontalHeaderLabels(tableView_h_headers);
        _tableView_Attributes->appendRow(QList<QStandardItem*>() << new QStandardItem("Elements") << new QStandardItem(QString::number(elemIDs.size())) << new QStandardItem(elemStr));
        _tableView_Attributes->appendRow(QList<QStandardItem*>() << new QStandardItem("Nodes") << new QStandardItem(QString::number(nodeIDs.size())) << new QStandardItem(nodeStr));
        
        // 表格宽度自动根据UI进行计算，不可手动调整宽度
        _ui->tableView_Attributes->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        _ui->tableView_Attributes->setEditTriggers(QAbstractItemView::NoEditTriggers);
    }

    void GUIFESubSysAcousticDialog::initTableViewElements()
    {
        if (!_obj) return;
        //获取离散数据
        Acoustics::FITKAcousticsDiscModel* discMgr = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discMgr) return;
        //获取FE子系统管理器
        Acoustics::FITKAcousticsFEModel* feModel = discMgr->getFEModel();
        if (!feModel) return;
        //获取单元管理器
        Acoustics::FITKAcousticsFESubSysElementList* elementList = feModel->getFESubSysElementList();
        if (!elementList) return;
        QList<int> elemIDs = _obj->getElementsID();
        //写出单元表格
        _tableView_Elements->clear();
        QStringList tVElement_h_headers;
        tVElement_h_headers << tr("Element ID") << tr("Node IDs");
        _tableView_Elements->setHorizontalHeaderLabels(tVElement_h_headers);
        for (int i = 0; i < elemIDs.size(); ++i)
        {
            int eID = elemIDs.at(i);
            //获取单元数据
            Interface::FITKAbstractElement* element = elementList->getElementByID(eID);
            if (!element) continue;
            QList<int> nodes = element->getAllNodes();
            QStringList nodeIDStr;
            for (int nID : nodes)
                nodeIDStr.append(QString::number(nID));
            //设置表格内容
            _tableView_Elements->setItem(i, 0, new QStandardItem(QString::number(eID)));
            _tableView_Elements->setItem(i, 1, new QStandardItem(nodeIDStr.join("; ")));
        }
        // 表格宽度自动根据UI进行计算，不可手动调整宽度
        _ui->tableView_Elements->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        _ui->tableView_Elements->setEditTriggers(QAbstractItemView::NoEditTriggers);
    }

    void GUIFESubSysAcousticDialog::initTableViewNodes()
    {
        if (!_obj) return;
        //获取离散数据
        Acoustics::FITKAcousticsDiscModel* discMgr = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discMgr) return;
        //获取节点管理器
        Acoustics::FITKAcousticsDiscNodeList* nodeList = discMgr->getNodes();
        if (!nodeList) return;
        QList<int> nodeIDs = _obj->getNodesID();
        //写出节点表格
        _tableView_Nodes->clear();
        QStringList tVNode_h_headers;
        tVNode_h_headers << tr("Node ID") << tr("X") << tr("Y") << tr("Z");
        _tableView_Nodes->setHorizontalHeaderLabels(tVNode_h_headers);
        for (int i = 0; i < nodeIDs.size(); ++i)
        {
            int nID = nodeIDs.at(i);
            //获取节点数据
            Core::FITKNode* node = nodeList->getNodeByID(nID);
            if (!node) continue;
            double coor[3]{ 0,0,0 };
            node->getCoor(coor);
            //设置表格内容
            _tableView_Nodes->setItem(i, 0, new QStandardItem(QString::number(nID)));
            _tableView_Nodes->setItem(i, 1, new QStandardItem(QString::number(coor[0])));
            _tableView_Nodes->setItem(i, 2, new QStandardItem(QString::number(coor[1])));
            _tableView_Nodes->setItem(i, 3, new QStandardItem(QString::number(coor[2])));
        }
        // 表格宽度自动根据UI进行计算，不可手动调整宽度
        _ui->tableView_Nodes->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
        _ui->tableView_Nodes->setEditTriggers(QAbstractItemView::NoEditTriggers);
    }

    void GUIFESubSysAcousticDialog::initGeometryProp()
    {
        double volume = 0.0, area = 0.0, mass = 0.0;
        _ui->lineEdit_Volume->setText(QString::number(volume));
        _ui->lineEdit_Area->setText(QString::number(area));
        _ui->lineEdit_Mass->setText(QString::number(mass));
    }

    void GUIFESubSysAcousticDialog::initDampingLossComboBox()
    {
        //清空数据下拉链表
        _ui->comboBox_DampingLoss->clear();
        _ui->comboBox_Absorption->clear();
        //初始化损耗因子下拉列表
        Acoustics::FITKAcousticsPhysics* phyMgr = FITKAPP->getGlobalData()->getPhysicsData<Acoustics::FITKAcousticsPhysics>();
        if (!phyMgr)return;
        //获取频谱管理器
        Acoustics::FITKAcousticsSpectraManager* spectraMgr = phyMgr->getFITKAcousticsSpectraManager();
        if (!spectraMgr)return;
        QList<Acoustics::FITKAcousticsAbstractSpectra*> spectraList = spectraMgr->getSpectraByType(Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Damping);
        for (QList<Acoustics::FITKAcousticsAbstractSpectra*>::iterator iter = spectraList.begin(); iter != spectraList.end(); ++iter)
        {
            if (*iter == nullptr)continue;
            _ui->comboBox_DampingLoss->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
        }

        spectraList = spectraMgr->getSpectraByType(Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Absorption);
        for (QList<Acoustics::FITKAcousticsAbstractSpectra*>::iterator iter = spectraList.begin(); iter != spectraList.end(); ++iter)
        {
            if (*iter == nullptr)continue;
            _ui->comboBox_Absorption->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
        }
    }

    void GUIFESubSysAcousticDialog::initFluidComboBox()
    {
        //清空数据下拉链表
        _ui->comboBox_Fluid->clear();
        //初始化损耗因子下拉列表
        Acoustics::FITKAcousticsPhysics* phyMgr = FITKAPP->getGlobalData()->getPhysicsData<Acoustics::FITKAcousticsPhysics>();
        if (!phyMgr)return;
        //获取材料管理器
        Acoustics::FITKAcousticsMaterialManager* materialMgr = phyMgr->getMaterialManager();
        if (!materialMgr)return;
        QList<Acoustics::FITKAcousticsAbsMaterial*> materialList = materialMgr->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::AcousticsMaterialType::Fluid);
        for (QList<Acoustics::FITKAcousticsAbsMaterial*>::iterator iter = materialList.begin(); iter != materialList.end(); ++iter)
        {
            if (*iter == nullptr)continue;
            _ui->comboBox_Fluid->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
        }
    }

    void GUIFESubSysAcousticDialog::getDataFormWidget()
    {
        Acoustics::FITKFESubSysAcoustic* data = dynamic_cast<Acoustics::FITKFESubSysAcoustic*>(_obj);
        if (!data) return;
        //从界面获取数据
        int materialID = _ui->comboBox_Fluid->currentData().toInt();
        int dampingID = _ui->comboBox_DampingLoss->currentData().toInt();
        if (_ui->radioButton_Absorption->isChecked())
            dampingID = _ui->comboBox_Absorption->currentData().toInt();
        //设置数据
        data->setAllElementPropID(materialID);
        data->setDampingSpectraID(dampingID);
    }

    QString GUIFESubSysAcousticDialog::getNameFormWidget()
    {
        return _ui->lineEdit_Name->text();
    }
}
